package org.malred.hospital.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.malred.hospital.common.R;

import org.malred.hospital.dto.MedicineListDto;
import org.malred.hospital.dto.MedicineListStatisticDto;
import org.malred.hospital.entity.*;
import org.malred.hospital.entity.TbMedicine;
import org.malred.hospital.entity.TbMedicine;
import org.malred.hospital.service.MedicineCategoryService;
import org.malred.hospital.service.MedicineService;
import org.malred.hospital.service.MedicineService;
import org.malred.hospital.utils.ConstValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/medicine")
public class MedicineController extends BaseController<TbMedicine> {
    @Autowired
    private MedicineService service;
    @Autowired
    private MedicineCategoryService categoryService;

    @Override
    public R<List<TbMedicine>> findAll() {
        try {
            return R.success(service.list());
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    @GetMapping("/category/findAll")
    public R<List<TbMedicineCategory>> findAllCategory() {
        try {
            return R.success(categoryService.list());
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    @GetMapping("/dto/findAll")
    public R<List<MedicineListDto>> findAllDto() {
        try {
            List<MedicineListDto> list = service.list().stream()
                    .map(this::getMedicineListDto)
                    .collect(Collectors.toList());
            return R.success(list);
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    @GetMapping("/statistic")
    public R<List<MedicineListStatisticDto>> findAllStatisticDto() {
        List<MedicineListDto> list = service.list().stream()
                .map(this::getMedicineListDto)
                .collect(Collectors.toList());

        List<MedicineListStatisticDto> collect = categoryService.list().stream().map(c -> {
            MedicineListStatisticDto statisticDto = new MedicineListStatisticDto();
            statisticDto.setNumber(0L);
            statisticDto.setName(c.getCategory());
            for (MedicineListDto dto : list) {
                if (dto.getCategory().equals(c.getCategory())) {
                    statisticDto.setNumber(
                            statisticDto.getNumber() + dto.getNumber()
                    );
                }
            }
            return statisticDto;
        }).collect(Collectors.toList());

        return R.success(collect);
    }

    @Override
    public R<TbMedicine> findById(@PathVariable Long id) {
        return R.success(service.getById(id));
    }

    @GetMapping("/find/name/{name}")
    public R<List<MedicineListDto>> findByName(@PathVariable String name) {
        LambdaQueryWrapper<TbMedicine> qw = new LambdaQueryWrapper<>();
        qw.like(TbMedicine::getName, name);
        List<MedicineListDto> list = service.list(qw).stream()
                .map(this::getMedicineListDto)
                .collect(Collectors.toList());
        return R.success(list);
    }

    // 从tbmedicine组装dto
    private MedicineListDto getMedicineListDto(TbMedicine c) {
        MedicineListDto dto = new MedicineListDto();
        dto.setId(c.getId());
        dto.setName(c.getName());
        dto.setNumber(c.getNumber());
        dto.setPrice(c.getPrice());
        TbMedicineCategory category = categoryService.getById(c.getCategoryId());
        dto.setCategory(category.getCategory());
        return dto;
    }

    @GetMapping("/page")
    public R<List<MedicineListDto>> page(int page, int size) {
        //分页构造器
        Page<TbMedicine> pageInfo = new Page<>(page, size);
        //条件构造器
        LambdaQueryWrapper<TbMedicine> queryWrapper = new LambdaQueryWrapper<>();
        //添加排序条件，根据sort进行排序
        queryWrapper.orderByAsc(TbMedicine::getCreateTime);

        //分页查询
        service.page(pageInfo, queryWrapper);

        List<MedicineListDto> collect = pageInfo.getRecords()
                .stream().map(this::getMedicineListDto)
                .collect(Collectors.toList());

        return R.success(collect);
    }

    @GetMapping("/count")
    public R<Integer> count() {
        return R.success(service.count());
    }

    @Override
    public R<TbMedicine> insert(@RequestBody TbMedicine dto) {
        if (dto == null) {
            return R.error("添加 [Medicine] 失败");
        }
        if (dto.getName().isEmpty()) {
            return R.error("添加 [Medicine] 失败, 药品名称不能为空");
        }
        if (dto.getName().matches(ConstValues.OTHER_CHAT_REGEX)) {
            return R.error("添加 [Medicine] 失败, 药品名称不能有特殊符号");
        }

        dto.setNumber(0L);
        if (service.save(dto)) {
            log.info("medicine: {}", dto.toString());
            return R.success(dto);
        } else {
            return R.error("添加 [Medicine] 失败");
        }
    }

    @Override
    public R<TbMedicine> update(@RequestBody TbMedicine dto) {
        if (dto == null || dto.getName().isEmpty()) {
            return R.error("更新信息不能为空");
        }
        if (service.saveOrUpdate(dto)) {
            return R.success(dto);
        } else {
            return R.error("修改 [Medicine] 失败");
        }
    }

    @Override
    public R<TbMedicine> delete(@PathVariable Long id) {
        if (service.removeById(id)) {
            return R.success(null);
        } else {
            return R.error("删除 [Medicine] 失败");
        }
    }
}
